#!/usr/bin/env python3
"""
演示 $ref 引用解析优化的效果
"""

# 模拟优化前的行为
def extract_parameters_old(api_details):
    """原始的参数提取方法（简化版）"""
    parameters = []
    
    # 提取路径和查询参数
    for param in api_details.get('parameters', []):
        param_info = {
            'name': param.get('name', ''),
            'type': param.get('type', 'string'),
            'in': param.get('in', 'query'),
            'required': param.get('required', False),
            'description': param.get('description', ''),
            'schema': param.get('schema', {})
        }
        parameters.append(param_info)
    
    # 提取请求体参数（原始版本不处理 $ref）
    request_body = api_details.get('requestBody', {})
    if request_body:
        content = request_body.get('content', {})
        for content_type, schema_info in content.items():
            schema = schema_info.get('schema', {})
            if 'properties' in schema:
                for prop_name, prop_details in schema['properties'].items():
                    param_info = {
                        'name': prop_name,
                        'type': prop_details.get('type', 'string'),
                        'in': 'body',
                        'required': prop_name in schema.get('required', []),
                        'description': prop_details.get('description', ''),
                        'schema': prop_details
                    }
                    parameters.append(param_info)
            elif '$ref' in schema:
                # 原始版本只返回引用信息，不解析具体内容
                param_info = {
                    'name': 'requestBody',
                    'type': 'object',
                    'in': 'body',
                    'required': True,
                    'description': f"Request body with reference: {schema['$ref']}",
                    'schema': schema
                }
                parameters.append(param_info)
    
    return parameters

# 模拟优化后的行为
def extract_parameters_new(api_details, api_docs):
    """优化后的参数提取方法（简化版）"""
    
    def resolve_ref(ref_path, docs):
        """解析 $ref 引用"""
        if not ref_path.startswith('#/'):
            return {}
        
        path_parts = ref_path[2:].split('/')
        current = docs
        for part in path_parts:
            if isinstance(current, dict) and part in current:
                current = current[part]
            else:
                return {}
        return current if isinstance(current, dict) else {}
    
    def extract_properties_from_schema(schema, docs, visited_refs=None):
        """从 schema 中提取属性，解析 $ref 引用"""
        if visited_refs is None:
            visited_refs = set()
        
        parameters = []
        
        # 处理 $ref 引用
        if '$ref' in schema:
            ref_path = schema['$ref']
            if ref_path in visited_refs:
                return parameters
            
            visited_refs.add(ref_path)
            resolved_schema = resolve_ref(ref_path, docs)
            if resolved_schema:
                parameters.extend(extract_properties_from_schema(
                    resolved_schema, docs, visited_refs.copy()
                ))
            visited_refs.discard(ref_path)
            return parameters
        
        # 处理直接属性
        if 'properties' in schema:
            required_fields = schema.get('required', [])
            for prop_name, prop_details in schema['properties'].items():
                if '$ref' in prop_details:
                    ref_path = prop_details['$ref']
                    if ref_path not in visited_refs:
                        visited_refs.add(ref_path)
                        resolved_prop = resolve_ref(ref_path, docs)
                        if resolved_prop:
                            # 添加对象本身
                            param_info = {
                                'name': prop_name,
                                'type': 'object',
                                'in': 'body',
                                'required': prop_name in required_fields,
                                'description': prop_details.get('description', resolved_prop.get('description', '')),
                                'schema': resolved_prop
                            }
                            parameters.append(param_info)
                            
                            # 添加嵌套属性
                            nested_params = extract_properties_from_schema(
                                resolved_prop, docs, visited_refs.copy()
                            )
                            for nested_param in nested_params:
                                nested_param['name'] = f"{prop_name}.{nested_param['name']}"
                                nested_param['description'] = f"[{prop_name}] {nested_param['description']}"
                            parameters.extend(nested_params)
                        visited_refs.discard(ref_path)
                else:
                    # 常规属性
                    param_info = {
                        'name': prop_name,
                        'type': prop_details.get('type', 'string'),
                        'in': 'body',
                        'required': prop_name in required_fields,
                        'description': prop_details.get('description', ''),
                        'schema': prop_details
                    }
                    parameters.append(param_info)
        
        return parameters
    
    parameters = []
    
    # 提取路径和查询参数
    for param in api_details.get('parameters', []):
        param_info = {
            'name': param.get('name', ''),
            'type': param.get('type', 'string'),
            'in': param.get('in', 'query'),
            'required': param.get('required', False),
            'description': param.get('description', ''),
            'schema': param.get('schema', {})
        }
        parameters.append(param_info)
    
    # 提取请求体参数（优化版本处理 $ref）
    request_body = api_details.get('requestBody', {})
    if request_body:
        content = request_body.get('content', {})
        for content_type, schema_info in content.items():
            schema = schema_info.get('schema', {})
            body_params = extract_properties_from_schema(schema, api_docs)
            parameters.extend(body_params)
    
    return parameters

# 测试数据
MOCK_API_DOCS = {
    "definitions": {
        "VirtualVolumeCreateVo": {
            "type": "object",
            "required": ["name", "size"],
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Volume name"
                },
                "size": {
                    "type": "integer",
                    "description": "Volume size in GB"
                },
                "description": {
                    "type": "string",
                    "description": "Volume description"
                },
                "tags": {
                    "$ref": "#/definitions/TagList"
                }
            }
        },
        "TagList": {
            "type": "object",
            "properties": {
                "key": {
                    "type": "string",
                    "description": "Tag key"
                },
                "value": {
                    "type": "string",
                    "description": "Tag value"
                }
            }
        }
    }
}

MOCK_API_DETAILS = {
    'method': 'POST',
    'path': '/virtual-volumes',
    'summary': 'Create virtual volume',
    'parameters': [],
    'requestBody': {
        'content': {
            'application/json': {
                'schema': {
                    '$ref': '#/definitions/VirtualVolumeCreateVo'
                }
            }
        }
    }
}

def demo():
    """演示优化效果"""
    print("=" * 60)
    print("Swagger $ref 引用解析优化演示")
    print("=" * 60)
    
    print("\n1. 优化前的参数提取结果:")
    print("-" * 40)
    old_params = extract_parameters_old(MOCK_API_DETAILS)
    for i, param in enumerate(old_params, 1):
        print(f"{i}. {param['name']} ({param['type']}) - {param['description']}")
    
    print(f"\n总计: {len(old_params)} 个参数")
    
    print("\n2. 优化后的参数提取结果:")
    print("-" * 40)
    new_params = extract_parameters_new(MOCK_API_DETAILS, MOCK_API_DOCS)
    for i, param in enumerate(new_params, 1):
        required = "必需" if param['required'] else "可选"
        print(f"{i}. {param['name']} ({param['type']}, {required}) - {param['description']}")
    
    print(f"\n总计: {len(new_params)} 个参数")
    
    print("\n3. 优化效果对比:")
    print("-" * 40)
    print(f"优化前: {len(old_params)} 个参数")
    print(f"优化后: {len(new_params)} 个参数")
    print(f"增加了: {len(new_params) - len(old_params)} 个参数")
    
    print("\n4. 新增的参数详情:")
    print("-" * 40)
    old_names = {p['name'] for p in old_params}
    new_names = {p['name'] for p in new_params}
    added_names = new_names - old_names
    
    for name in sorted(added_names):
        param = next(p for p in new_params if p['name'] == name)
        required = "必需" if param['required'] else "可选"
        print(f"+ {name} ({param['type']}, {required}) - {param['description']}")
    
    print("\n" + "=" * 60)
    print("优化成功！现在 POST/PUT 请求可以获取完整的参数信息了。")
    print("=" * 60)

if __name__ == "__main__":
    demo()
